#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2003,2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
####################################################################
#
#   testlinecont command
#
#   Syntax:  testlinecont {-f <frame> -g <cage> 
#                        [{-c <chip>|-a <adapter>} [-o <port>]] 
#                        [-n] | --help }
#
#            -f <frame>      - Specifies the frame for the link(s) to be
#				tested
#            -g <cage>       - Specifies the cage for the link(s) to be
#				tested
#            -c <chip>       - Specifies the chip for the link(s) to be
#                               tested
#            -a <adapter>    - Specifies the adapter for the link(s) to be
#                               tested
#            -o <port>       - Specifies the port for the link(s) to be
#                               tested
#            -n              - Specifies that no confirmation prompts are
#                               to be issuedr before performing the test(s)
#            --help          - Prints this message
#
####################################################################
#
#   Initial version - 12/11/02
#
####################################################################

use Getopt::Long;

#
# Include the following Perl script here to help process the i_stub_FS 
# return codes.
#
require "/opt/hsc/bin/i_stub_msg.pl" ;

sub bynumber { $a <=> $b; }

sub exit_routine {
    
	# Print out results array if there were any errors

	if ($BAD_RESULTS == 1) {
		if ($NUM_BAD_RESULTS == 1) {
			print "\nThe following test was unsuccessful:\n";
		} else {
			print "\nThe following tests were unsuccessful:\n";
		}
		
		for ($m = 0; $m < $NUM_BAD_RESULTS; $m++) {
			$i_stub_return = $BAD_RESULTS_i_stub_return[$m];
			&i_stub_msg;
			print "\tFrame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $BAD_RESULTS_DEVICE[$m], " Port = ", $BAD_RESULTS_PORT[$m], ": ", $RC_MSG;
		}
		$ret = 1;
	} else {
		if ($TEST_RUN == 1) {
			print "\nAll devices tested successfully.\n";
		}
		$ret = 0;
	}

	exit $ret; 

} # end exit_routine subroutine

sub prompt {
	$GO_AHEAD = 0;
	print "The targeted link will be removed from the active configuration for the duration of the test.  Do you wish to continue? (yes/no)\n";
	print "\t\tFrame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $DEVICE, " Port = ", $PORT, "\n";
	$RESPONSE = <STDIN>;
	chomp $RESPONSE;
	if (($RESPONSE eq "yes") || ($RESPONSE eq "y")) {
		$GO_AHEAD = 1;
	}
}

################################################################################
#
# start main body of code
#
################################################################################
$PRGRM  = "testlinecont";
$BIN    = "/opt/hsc/bin"; 
$I_STUB_FS = "/opt/hsc/bin/i_stub_FS";

$MAX_CHIPS = 8;
$MAX_ADAP = 8;
$MAX_CHIP_PORTS = 8;
$MAX_ADAP_PORTS = 2;
$BAD_LOC_ID = 51;

$SWITCH = 1;
$STARTED = 0 ;

$TEST_RUN = 0;

$BAD_RESULTS = 0;
$NUM_BAD_RESULTS = 0;

$USAGE = "Usage:  testlinecont {-f <frame> -g <cage> [{-c <chip>|-a <adapter>} [-o <port>]] [-n] | --help }\n";

# First check for existence of parameters
if ($#ARGV == -1) {
#	print "No parms\n";     #DEBUG
	print $USAGE;
	$ret = 1;
	&exit_routine;
}

# Get parameters used

Getopt::Long::Configure("no_ignore_case");
$result = GetOptions(
        "help" => \$help,
        "f=s" => \$frame,
        "g=s" => \$cage,
        "c=s" => \$chip,
        "a=s" => \$adapter,
        "o=s" => \$port,
        "n" => \$no_prompt,
);

#print "GetOptions rc is ", $result, " .\n";

if ($result == 0) {
	# Bad result from GetOptions
#	print "Bad result from GetOptions\n";     #DEBUG
	print $USAGE;      #USAGE
	$ret = 1;
	&exit_routine;
}

if ($help) {
	# help was asked for
#	print "help was specified\n";     #DEBUG
	print $USAGE;      #USAGE
	$ret = 0;
	&exit_routine;
}

if (defined $frame) {
	$frame_parm = $frame;
	if ($frame_parm =~ /\D/) {
#		print "Bad -f value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		&exit_routine;
	}
}
else {
	# No -f or nothing else was specified after -f
#	print "No -f value\n";     #DEBUG
	print $USAGE;
	$ret = 1;
	&exit_routine;
}

if (defined $cage) {
	$cage_parm = $cage;
	if ($cage_parm =~ /\D/) {
#		print "Bad -g value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		&exit_routine;
	}
	else {
		#CHECK ON MAX CAGE VALUE?
	}
}
else {
	# No -g or nothing else was specified after -g
#	print "No -g value\n";     #DEBUG
	print $USAGE;
	$ret = 1;
	&exit_routine;
}

if (defined $chip) {
	$chip_parm = $chip;
	if ($chip_parm =~ /\D/) {
#		print "Bad -c value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	if (($chip_parm < 0) || ($chip_parm > 7)) {
#		print "Bad -c value - not 0-7\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	$h_parm = $chip;
}

if (defined $adapter) {
	$adap_parm = $adapter;
	if ($adap_parm =~ /\D/) {
#		print "Bad -a value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	if (($adap_parm < 0) || ($adap_parm > 7)) {
#		print "Bad -a value - not 0-7\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	$h_parm = $adapter;
}

if (defined $port) {
	$port_parm = $port;
	if ($port_parm =~ /\D/) {
#		print "Bad -o value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	if (defined $chip) {
		if (($port_parm < 0) || ($port_parm > 7)) {
#			print "Bad -o value - not 0-7\n";     #DEBUG
			print $USAGE;
			$ret = 1;
			exit $ret;
		}
	} else {
		if (($port_parm < 0) || ($port_parm > 1)) {
#			print "Bad -p value - not 0-1\n";     #DEBUG
			print $USAGE;
			$ret = 1;
			exit $ret;
		}
	}
}

# Make sure no invalid combos were passed
if ((defined $chip) && (defined $adapter)) {
#	print "Cannot specify -c and -a together\n";    #DEBUG
	print $USAGE;
	$ret = 1;
	exit $ret;
}

if ((defined $port) && ((!defined $chip) && (!defined $adapter))) {
#	print "If -o, then must have either -a or -c\n";  #DEBUG
	print $USAGE;
	$ret = 1;
	exit $ret;
}

# Now that we've determined that the user specified all the required parms
#      and passed reasonable values with them, see how many times we have
#      to issue the i_stub_FS command
if (defined $port) {
	# -o was specified, so we're only testing one link
	if (not defined $no_prompt) {
		# -n was not specified, so go issue confirmation prompt
		$DEVICE = $h_parm;
		$PORT = $port_parm;
		&prompt;
		if ($GO_AHEAD == 0) {
			&exit_routine;
		}
	}

	$TEST_RUN = 1;
	print "\tIssuing Line Continuity Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $h_parm, " Port = ", $port_parm, "\n";
	$i_stub_return = `$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $h_parm -p $port_parm`;
#		print "$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $h_parm -p $port_parm\n";

	# Check return code from i_stub_FS
	if ($i_stub_return != 0) {
		$BAD_RESULTS = 1;
		$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
		$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $h_parm;
		$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $port_parm;
		$NUM_BAD_RESULTS += 1;
	}
}
elsif (defined $chip) {
	# No -o but there was a -c so we want to test multiple ports
	#   of the same chip
	LOOP: for ($i = 0; $i < $MAX_CHIP_PORTS; $i++) {
		if (not defined $no_prompt) {
			# -n was not specified, so go issue confirmation prompt
			$DEVICE = $h_parm;
			$PORT = $i;
			&prompt;
			if ($GO_AHEAD == 0) {
				next LOOP;
			}
		}

		$TEST_RUN = 1;
		print "\tIssuing Line Continuity Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $h_parm, " Port = ", $i, "\n";
		$i_stub_return = `$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $h_parm -p $i`;
#		print "$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $h_parm -p $i\n";

			# Check return code from i_stub_FS
			if ($i_stub_return != 0) {
				$BAD_RESULTS = 1;
				$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
				$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $h_parm;
				$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $i;
				$NUM_BAD_RESULTS += 1;
			}
	}
}
elsif (defined $adapter) {
	# No -o but there was a -a so we want to test multiple ports
	#   of the same adapter
	LOOP: for ($i = 0; $i < $MAX_ADAP_PORTS; $i++) {
		if (not defined $no_prompt) {
			# -n was not specified, so go issue confirmation prompt
			$DEVICE = $adap_parm;
			$PORT = $i;
			&prompt;
			if ($GO_AHEAD == 0) {
				next LOOP;
			}
		}

		$TEST_RUN = 1;
		print "\tIssuing Line Continuity Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $adap_parm, " Port = ", $i, "\n";
		$i_stub_return = `$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $adap_parm -p $i`;
#		print "$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $h_parm -p $i\n";

			# Check return code from i_stub_FS
			if ($i_stub_return != 0) {
				$BAD_RESULTS = 1;
				$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
				$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $adap_parm;
				$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $i;
				$NUM_BAD_RESULTS += 1;
			}
	}
}
else {
	# Only -f and -g were specified, so we want to test all the ports
        #   of a switch or in a server.  Assume switch first.
	OUTER: for ($i = 0; $i < $MAX_CHIPS; $i++) {
		INNER: for ($j = 0; $j < $MAX_CHIP_PORTS; $j++) {
			if (not defined $no_prompt) {
				# -n was not specified, so go issue confirmation prompt
				$DEVICE = $i;
				$PORT = $j;
				&prompt;
				if ($GO_AHEAD == 0) {
                                        $STARTED = 1;
					next INNER;
				}
			}

			$TEST_RUN = 1;
			$i_stub_return = `$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $i -p $j`;
#			print "$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $i -p $j\n";
		       # Check return code from i_stub_FS
	                if ($i_stub_return != 0) {
				$BAD_RESULTS = 1;
				$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
				$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $i;
				$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $j;
				$NUM_BAD_RESULTS += 1;
				if ($i_stub_return == $BAD_LOC_ID) {
					$SWITCH = 0;
					if ($STARTED == 1) {
						$NUM_BAD_RESULTS -= 1;
					}
					last OUTER;
				}
				else {
			                print "\tIssuing Line Continuity Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $i, " Port = ", $j, "\n";
					$STARTED = 1;
				}
                       }
		       else {
			       print "\tIssuing Line Continuity Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $i, " Port = ", $j, "\n";
			       $STARTED = 1;
		       }
		}
	}
}

# See if we bailed out because we got an invalid location id return code.  If so, we need
#   to continue with the adapter testing
if (($SWITCH == 0) && ($STARTED == 1)) {
	for ($k = 1; $k < $MAX_ADAP; $k++) {
		INNER: for ($l = 0; $l < $MAX_ADAP_PORTS; $l++) {
			if (not defined $no_prompt) {
				# -n was not specified, so go issue confirmation prompt
				$DEVICE = $k;
				$PORT = $l;
				&prompt;
				if ($GO_AHEAD == 0) {
					next INNER;
				}
			}

			$TEST_RUN = 1;
			print "\tIssuing Line Continuity Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $k, " Port = ", $l, "\n";
			$i_stub_return = `$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $k -p $l`;
#		print "$I_STUB_FS diag -t 1 -f $frame_parm -c $cage_parm -h $k -p $l\n";
			# Check return code from i_stub_FS
			if ($i_stub_return != 0) {
				$BAD_RESULTS = 1;
				$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
				$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $k;
				$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $l;
				$NUM_BAD_RESULTS += 1;
			}
                }
        }
}

&exit_routine;

